{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "06a3bbec",
   "metadata": {},
   "source": [
    "下面用代码实现循环神经网络。首先读取数据，使用《小王子》这本书作为训练语料。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "58df11c1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "115\n"
     ]
    },
    {
     "data": {
      "image/png": "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ly5d0rZt2750fKRrNypfWkpJSVFUVFSv4mtubu5V3vijlStX6tVXX9WxY8c0fvx4Z7/P55Mk1rIPtbW1am5uVm5urqKjoxUdHa3q6mr90z/9k6Kjo531Ye16S0tL0+233x6271vf+pY++OADSfx3dyV/93d/p3Xr1unBBx9UTk6OHn74Yf3t3/6tysvLJbF2kbiatfL5fOrq6lJLS0u/Y0az7u5uLViwQA0NDaqqqnKuxkiDt3ajMmRiY2OVm5urqqqqsP1VVVXKz88fplldn4wxWrFihfbt26ejR48qMzMz7HhmZqZ8Pl/YWnZ1dam6unrUr+XMmTNVX1+vuro6Z8vLy9Pf/M3fqK6uTrfeeitr14/vfve7vT7m/5vf/EYZGRmS+O/uSj799FPdcEP4/9qjoqKcj1+zdlfvatYqNzdXMTExYWOampp0+vTpUb+en0fM2bNndeTIESUnJ4cdH7S1i+BNySPK5x+/fuGFF8y7775riouLTXx8vDl37txwT+268thjjxmPx2OOHz9umpqanO3TTz91xmzcuNF4PB6zb98+U19fbx566KFR+1HOL/Onn1oyhrXrzxtvvGGio6PN008/bc6ePWteeuklM2bMGLN7925nDGvXt8WLF5uvfe1rzsev9+3bZ1JSUsyaNWucMazdF9rb283bb79t3n77bSPJbN682bz99tvOJ2uuZq2WLVtmxo8fb44cOWLeeustM2PGjFHx8esrrV13d7eZN2+eGT9+vKmrqwt7/giFQs45BmPtRm3IGGPMP//zP5uMjAwTGxtrvvOd7zgfKcYXJPW5bd++3Rlz6dIl89RTTxmfz2fcbreZMmWKqa+vH75JX8cuDxnWrn+vvfaayc7ONm6329x2223m5z//edhx1q5vbW1t5oknnjATJkwwN954o7n11lvNk08+Gfbkwdp94dixY33+P27x4sXGmKtbq87OTrNixQqTlJRk4uLizNy5c80HH3wwDI/mq3WltWtoaOj3+ePYsWPOOQZj7VzGGBPp5SIAAIDrwah8jwwAABgZCBkAAGAtQgYAAFiLkAEAANYiZAAAgLUIGQAAYC1CBgAAWIuQAQAA1iJkAACAtQgZAABgLUIGAABY6/8B1JIdsWQBRRgAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "\n",
    "# 导入前面实现的小王子数据集\n",
    "sys.path.append('./code')\n",
    "from my_utils import TheLittlePrinceDataset\n",
    "\n",
    "dataset = TheLittlePrinceDataset()\n",
    "\n",
    "# 统计每句话的长度\n",
    "sent_lens = []\n",
    "max_len = -1\n",
    "for sentence in dataset.tokens:\n",
    "    sent_len = len(sentence)\n",
    "    sent_lens.append(sent_len)\n",
    "    if sent_len > max_len:\n",
    "        max_len = sent_len\n",
    "        longest = sentence\n",
    "print(max_len)\n",
    "\n",
    "# 简单看一下语料中序列长度的分布\n",
    "import matplotlib.pyplot as plt\n",
    "plt.hist(sent_lens, bins=20)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf1e69d9",
   "metadata": {},
   "source": [
    "接下来建立词表，截断过长的序列，将序列填充（padding）到相同长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f25456ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1089 115\n",
      "(1088, 40)\n",
      "[  4  16  19 733 734 735 733 734 735   2  63  20   9   1   1   2   1  10\n",
      " 736 737   4  16  19  21   1   2  30 371 209  33 294   3   0   0   0   0\n",
      "   0   0   0   0]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "dataset.build_vocab()\n",
    "sent_tokens = dataset.convert_tokens_to_ids()\n",
    "# 截断和填充\n",
    "max_len=40\n",
    "for i, tokens in enumerate(sent_tokens):\n",
    "    tokens = tokens[:max_len]\n",
    "    tokens += [dataset.token2id['<pad>']] * (max_len - len(tokens))\n",
    "    sent_tokens[i] = tokens\n",
    "sent_tokens = np.array(sent_tokens)\n",
    "\n",
    "print(len(dataset.tokens), max([len(x) for x in dataset.tokens]))\n",
    "print(sent_tokens.shape)\n",
    "print(sent_tokens[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "06e6fb52",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "import torch\n",
    "from torch import nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "# 定义一个正态分布的函数用于初始化参数\n",
    "def normal(shape):\n",
    "    return torch.randn(size=shape) * 0.01\n",
    "\n",
    "class RNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(RNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 将输入与隐状态分别经过线性变化后相加\n",
    "        self.W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "    \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),)\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            # 输入hidden_state与inputs经过线性变换后相加，\n",
    "            # 输出的hidden_state也是下一时刻输入的hidden_state\n",
    "            xh = torch.mm(inputs[step], self.W_xh)\n",
    "            hh = torch.mm(hidden_state, self.W_hh)\n",
    "            hidden_state = xh + hh + self.b_h\n",
    "            hidden_state = torch.tanh(hidden_state)\n",
    "            hiddens.append(hidden_state)\n",
    "        # 返回所有时刻的hidden_state: seq_len * batch_size * hidden_size\n",
    "        # 以及最后时刻的hidden_state（可能用于后续输入）: \n",
    "        # batch_size * hidden_size\n",
    "        return torch.stack(hiddens, dim=0), (hidden_state,)\n",
    "\n",
    "# 在循环神经网络的基础上添加语言模型的输入输出、损失计算等\n",
    "class RNNLM(nn.Module):\n",
    "    def __init__(self, model, vocab_size, hidden_size):\n",
    "        super(RNNLM, self).__init__()\n",
    "        self.vocab_size = vocab_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.embedding = nn.Embedding(vocab_size, hidden_size)\n",
    "        self.model = model\n",
    "        self.W_hq = nn.Parameter(normal((hidden_size, vocab_size)))\n",
    "        self.b_q = nn.Parameter(torch.zeros(vocab_size))\n",
    "        \n",
    "    def forward(self, input_ids):\n",
    "        batch_size, seq_len = input_ids.shape\n",
    "        # input_ids形状为batch_size * seq_len，翻转为seq_len * batch_size，\n",
    "        # 将seq_len放在第一维方便计算\n",
    "        input_ids = torch.permute(input_ids, (1, 0))\n",
    "        # seq_len * batch_size * embed_size\n",
    "        embed = self.embedding(input_ids)\n",
    "        # batch_size * hidden_size\n",
    "        states = self.model.init_rnn_state(batch_size, self.hidden_size)\n",
    "        hiddens, _ = self.model(embed, states)\n",
    "    \n",
    "        hiddens = torch.flatten(hiddens[:-1], start_dim=0, end_dim=1)\n",
    "        output_states = torch.mm(hiddens, self.W_hq) + self.b_q\n",
    "        labels = torch.flatten(input_ids[1:], start_dim=0, end_dim=1)\n",
    "        loss_fct = nn.CrossEntropyLoss(ignore_index=0)\n",
    "        loss = loss_fct(output_states, labels)\n",
    "        return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45a010aa",
   "metadata": {},
   "source": [
    "下面展示使用梯度裁剪的循环神经网络语言模型的训练代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "760da2e1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1088, 40)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.4248: 100%|█| 200/200 [03:31<00:00,  1.06s\n"
     ]
    },
    {
     "data": {
      "image/png": "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sXr1ahw+fBjBwcGYNWuWtE+UMzh8+LDN9W3fvh0AcP3110vnONs9rKqqwvDhw7F69epmn2/PfXvkkUfw/fffY8OGDdi3bx8qKyuxcOFCmEwme11Gi1q7vurqahw9ehTPPfccjh49ik2bNuHs2bO4+uqrm5x7991329zXDz74wB7lt0tb9xBo+9+ls95DADbXlZubi//9738QBAHXXnutzXmOfA/b8xnhEH+LItkYN26ceN9999kci46OFp955hmZKuo8BQUFIgBx9+7d0rEVK1aIixcvlq+oy/TCCy+Iw4cPb/Y5s9ksBgcHi6+88op0rLa2VtTpdOJ//vMfO1XY+R5++GExKipKNJvNoig6/z0EIH7//ffS4/bct7KyMtHFxUXcsGGDdE52draoUCjEX3/91W61t8fF19ecQ4cOiQDE9PR06dj06dPFhx9+uGuL6yTNXWNb/y672z1cvHixOHPmTJtjznQPRbHpZ4Sj/C2yRaWRuro6xMXFYfbs2TbHZ8+ejQMHDshUVefR6/UAAF9fX5vju3btQmBgIAYMGIC7774bBQUFcpTXYcnJyQgNDUVkZCSWLVuG8+fPAwBSU1ORl5dncz/VajWmT5/utPezrq4On3/+Oe644w6bjTid/R421p77FhcXh/r6eptzQkNDMWTIEKe8t3q9HoIgwNvb2+b4F198AX9/fwwePBhPPPGEU7UEAq3/u+xO9zA/Px9bt27FnXfe2eQ5Z7qHF39GOMrfolNvStjZioqKYDKZEBQUZHM8KCgIeXl5MlXVOURRxGOPPYYpU6ZgyJAh0vF58+bh+uuvR0REBFJTU/Hcc89h5syZiIuLc4pVFsePH49PP/0UAwYMQH5+Pv71r39h0qRJSExMlO5Zc/czPT1djnIv2+bNm1FWVobbbrtNOubs9/Bi7blveXl5cHV1hY+PT5NznO1vtba2Fs888wxuvvlmm83eli9fjsjISAQHB+PkyZN49tlncfz4canrz9G19e+yO93DTz75BBqNBkuXLrU57kz3sLnPCEf5W2RQaUbj/1MFLDfw4mPO5sEHH8SJEyewb98+m+M33nij9P2QIUMwZswYREREYOvWrU3+6BzRvHnzpO+HDh2KiRMnIioqCp988ok0cK873c+PP/4Y8+bNQ2hoqHTM2e9hSzpy35zt3tbX12PZsmUwm814//33bZ67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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 梯度裁剪\n",
    "def grad_clipping(model, theta=1):\n",
    "    params = [p for p in model.parameters() if p.requires_grad]\n",
    "    norm = torch.sqrt(sum(torch.sum((p.grad ** 2)) for p in params))\n",
    "    if norm > theta:\n",
    "        for param in params:\n",
    "            param.grad[:] *= theta / norm\n",
    "    \n",
    "\n",
    "# 训练\n",
    "from torch.utils.data import DataLoader\n",
    "from torch.optim import SGD, Adam\n",
    "import numpy as np\n",
    "from tqdm import tqdm, trange\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def train_rnn_lm(data_loader, rnn, vocab_size, hidden_size=128, \n",
    "                 epochs=200, learning_rate=1e-3):\n",
    "    # 准备模型、优化器等\n",
    "    rnn_lm = RNNLM(rnn, vocab_size, hidden_size)\n",
    "    optimizer = Adam(rnn_lm.parameters(), lr=learning_rate)\n",
    "    rnn_lm.zero_grad()\n",
    "    rnn_lm.train()\n",
    "\n",
    "    epoch_loss = []\n",
    "    with trange(epochs, desc='epoch', ncols=60) as pbar:\n",
    "        for epoch in pbar:\n",
    "            for step, batch in enumerate(data_loader):\n",
    "                loss = rnn_lm(batch)\n",
    "                pbar.set_description(f'epoch-{epoch}, ' + \\\n",
    "                    f'loss={loss.item():.4f}')\n",
    "                loss.backward()\n",
    "                grad_clipping(rnn_lm)\n",
    "                optimizer.step()\n",
    "                rnn_lm.zero_grad()\n",
    "            epoch_loss.append(loss.item())\n",
    "\n",
    "    epoch_loss = np.array(epoch_loss)\n",
    "    # 打印损失曲线\n",
    "    plt.plot(range(len(epoch_loss)), epoch_loss)\n",
    "    plt.xlabel('training epoch')\n",
    "    plt.ylabel('loss')\n",
    "    plt.show()\n",
    "\n",
    "sent_tokens = np.array(sent_tokens)\n",
    "print(sent_tokens.shape)\n",
    "vocab_size = len(dataset.token2id)\n",
    "\n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long),\\\n",
    "    batch_size=16, shuffle=True)\n",
    "rnn = RNN(128, 128)\n",
    "train_rnn_lm(data_loader, rnn, vocab_size, hidden_size=128,\\\n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad30e705",
   "metadata": {},
   "source": [
    "接下来仿照循环神经网络实现长短期记忆，同样的接口使得我们可以重用之前的训练代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1995d027",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.3132: 100%|█| 200/200 [10:16<00:00,  3.08s\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 长短期记忆\n",
    "def gate_params(input_size, hidden_size):\n",
    "    return (nn.Parameter(normal((input_size, hidden_size))),\n",
    "           nn.Parameter(normal((hidden_size, hidden_size))),\n",
    "           nn.Parameter(torch.zeros(hidden_size)))\n",
    "\n",
    "class LSTM(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(LSTM, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 输入门参数\n",
    "        self.W_xi, self.W_hi, self.b_i = gate_params(input_size, hidden_size)\n",
    "        # 遗忘门参数\n",
    "        self.W_xf, self.W_hf, self.b_f = gate_params(input_size, hidden_size)\n",
    "        # 输出门参数\n",
    "        self.W_xo, self.W_ho, self.b_o = gate_params(input_size, hidden_size)\n",
    "        # 候选记忆单元参数\n",
    "        self.W_xc, self.W_hc, self.b_c = gate_params(input_size, hidden_size)\n",
    "        \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),\n",
    "               torch.zeros((batch_size, hidden_size), dtype=torch.float))\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, cell_state = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            I = torch.sigmoid(torch.mm(inputs[step], self.W_xi) \\\n",
    "                + torch.mm(hidden_state, self.W_hi) + self.b_i)\n",
    "            F = torch.sigmoid(torch.mm(inputs[step], self.W_xf) \\\n",
    "                + torch.mm(hidden_state, self.W_hf) + self.b_f)\n",
    "            O = torch.sigmoid(torch.mm(inputs[step], self.W_xo) \\\n",
    "                + torch.mm(hidden_state, self.W_ho) + self.b_o)\n",
    "            C_tilda = torch.tanh(torch.mm(inputs[step], self.W_xc) \\\n",
    "                + torch.mm(hidden_state, self.W_hc) + self.b_c)\n",
    "            cell_state = F * cell_state + I * C_tilda\n",
    "            hidden_state = O * torch.tanh(cell_state)\n",
    "            hiddens.append(hidden_state)\n",
    "        return torch.stack(hiddens, dim=0), (hidden_state, cell_state)\n",
    "    \n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "\n",
    "lstm = LSTM(128, 128)\n",
    "train_rnn_lm(data_loader, lstm, vocab_size, hidden_size=128, epochs=200, \n",
    "    learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6dafe1d",
   "metadata": {},
   "source": [
    "下面仿照长短期记忆实现门控循环单元。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7c4f3992",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.2236: 100%|█| 200/200 [08:30<00:00,  2.55s\n"
     ]
    },
    {
     "data": {
      "image/png": "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ggrAjBkzuOOOOxgwYABJSUm8++67pKWl8cADD9Tr9TExMaSnpxMQEHDW7qLGKiwsJC4ujvT09FY5o6i1Xx/oGluD1n59oGtsDVr79UHTX6NpmhQVFRETE3Pec50aVG699VZyc3P5wx/+QGZmJr169eLrr78mPj6+Xq+3WCzExsZe1BoDAwNb7S8etP7rA11ja9Darw90ja1Ba78+aNprPF9LSi2nBhWABx98kAcffNDZZYiIiIgLcvqsHxEREZGzUVA5Cy8vL5555pk6s4xak9Z+faBrbA1a+/WBrrE1aO3XB869RqcuoS8iIiJyLmpREREREZeloCIiIiIuS0FFREREXJaCioiIiLgsBZUzeOutt+jQoQPe3t7079+flStXOrukRpk1axYDBw4kICCAiIgIrr/+evbu3VvnnLvuugvDMOp8DRkyxEkVN9yzzz57Wv1RUVGO503T5NlnnyUmJgYfHx9GjRrFzp07nVhxw7Vv3/60azQMg4ceeghomffwhx9+YOLEicTExGAYBvPnz6/zfH3uW0VFBQ8//DDh4eH4+flx3XXXceTIkWa8irM71/VVVVXx5JNP0rt3b/z8/IiJieHnP/85GRkZdd5j1KhRp93XKVOmNPOVnN357mF9fi9b6j0Ezvg3aRgGL774ouMcV7+H9fmMcIW/RQWVn5g7dy7Tp0/nd7/7HcnJyYwYMYLx48eTlpbm7NIabMWKFTz00EOsXbuWxYsXU11dzdixYykpKalz3tVXX01mZqbj6+uvv3ZSxY3Ts2fPOvVv377d8dxf//pXXnnlFWbPns2GDRuIiopizJgxjn2iWoINGzbUub7FixcDcPPNNzvOaWn3sKSkhL59+zJ79uwzPl+f+zZ9+nS++uor5syZw6pVqyguLubaa6/FarU212Wc1bmur7S0lM2bN/P000+zefNm5s2bx759+7juuutOO/fee++tc1/feeed5ii/Xs53D+H8v5ct9R4Cda4rMzOTf/7znxiGwY033ljnPFe+h/X5jHCJv0VT6hg0aJD5wAMP1DnWrVs386mnnnJSRU0nOzvbBMwVK1Y4jt15553mpEmTnFfUBXrmmWfMvn37nvE5m81mRkVFmS+88ILjWHl5uRkUFGT+3//9XzNV2PQeffRRMyEhwbTZbKZptvx7CJhfffWV43F97lt+fr7p4eFhzpkzx3HO0aNHTYvFYi5atKjZaq+Pn17fmaxfv94EzNTUVMexkSNHmo8++ujFLa6JnOkaz/d72dru4aRJk8zRo0fXOdaS7qFpnv4Z4Sp/i2pROUVlZSWbNm1i7NixdY6PHTuWNWvWOKmqplNQUABAaGhonePLly8nIiKCLl26cO+995Kdne2M8hpt//79xMTE0KFDB6ZMmcKhQ4cASElJ4dixY3Xup5eXFyNHjmyx97OyspKPP/6Yu+++u85GnC39Hp6qPvdt06ZNVFVV1TknJiaGXr16tch7W1BQgGEYBAcH1zn+ySefEB4eTs+ePXniiSdaVEsgnPv3sjXdw6ysLBYuXMgvf/nL055rSffwp58RrvK36PS9flzJ8ePHsVqtREZG1jkeGRnJsWPHnFRV0zBNkxkzZjB8+HB69erlOD5+/Hhuvvlm4uPjSUlJ4emnn2b06NFs2rSpRayyOHjwYD766CO6dOlCVlYWf/zjHxk6dCg7d+503LMz3c/U1FRnlHvB5s+fT35+PnfddZfjWEu/hz9Vn/t27NgxPD09CQkJOe2clva3Wl5ezlNPPcXtt99eZ7O3qVOn0qFDB6KiotixYwczZ85k69atjq4/V3e+38vWdA8//PBDAgICmDx5cp3jLekenukzwlX+FhVUzuDU/1MF+w386bGWZtq0aWzbto1Vq1bVOX7rrbc6/t2rVy8GDBhAfHw8CxcuPO2PzhWNHz/e8e/evXuTlJREQkICH374oWPgXmu6n++99x7jx4+vszV6S7+HZ9OY+9bS7m1VVRVTpkzBZrPx1ltv1Xnu3nvvdfy7V69edO7cmQEDBrB582b69evX3KU2WGN/L1vaPQT45z//ydSpU/H29q5zvCXdw7N9RoDz/xbV9XOK8PBw3NzcTkuB2dnZpyXKluThhx9mwYIFLFu2jNjY2HOeGx0dTXx8PPv372+m6pqWn58fvXv3Zv/+/Y7ZP63lfqamprJkyRLuueeec57X0u9hfe5bVFQUlZWVnDhx4qznuLqqqipuueUWUlJSWLx4cZ3WlDPp168fHh4eLfa+/vT3sjXcQ4CVK1eyd+/e8/5dguvew7N9RrjK36KCyik8PT3p37//ac1yixcvZujQoU6qqvFM02TatGnMmzePpUuX0qFDh/O+Jjc3l/T0dKKjo5uhwqZXUVHB7t27iY6OdjS5nno/KysrWbFiRYu8n++//z4RERFcc8015zyvpd/D+ty3/v374+HhUeeczMxMduzY0SLubW1I2b9/P0uWLCEsLOy8r9m5cydVVVUt9r7+9Peypd/DWu+99x79+/enb9++5z3X1e7h+T4jXOZvsUmG5LYic+bMMT08PMz33nvP3LVrlzl9+nTTz8/PPHz4sLNLa7Bf/epXZlBQkLl8+XIzMzPT8VVaWmqapmkWFRWZjz/+uLlmzRozJSXFXLZsmZmUlGS2bdvWLCwsdHL19fP444+by5cvNw8dOmSuXbvWvPbaa82AgADH/XrhhRfMoKAgc968eeb27dvN2267zYyOjm4x11fLarWa7dq1M5988sk6x1vqPSwqKjKTk5PN5ORkEzBfeeUVMzk52THrpT737YEHHjBjY2PNJUuWmJs3bzZHjx5t9u3b16yurnbWZTmc6/qqqqrM6667zoyNjTW3bNlS52+zoqLCNE3TPHDggPncc8+ZGzZsMFNSUsyFCxea3bp1MxMTE13i+kzz3NdY39/LlnoPaxUUFJi+vr7m22+/fdrrW8I9PN9nhGm6xt+igsoZvPnmm2Z8fLzp6elp9uvXr8503pYEOOPX+++/b5qmaZaWlppjx44127RpY3p4eJjt2rUz77zzTjMtLc25hTfArbfeakZHR5seHh5mTEyMOXnyZHPnzp2O5202m/nMM8+YUVFRppeXl3n55Zeb27dvd2LFjfPtt9+agLl37946x1vqPVy2bNkZfzfvvPNO0zTrd9/KysrMadOmmaGhoaaPj4957bXXusx1n+v6UlJSzvq3uWzZMtM0TTMtLc28/PLLzdDQUNPT09NMSEgwH3nkETM3N9e5F3aKc11jfX8vW+o9rPXOO++YPj4+Zn5+/mmvbwn38HyfEabpGn+LRk2xIiIiIi5HY1RERETEZSmoiIiIiMtSUBERERGXpaAiIiIiLktBRURERFyWgoqIiIi4LAUVERERcVkKKiIiIuKyFFREpF7at2/P3/72t3qfv3z5cgzDID8//6LV5Eoa+vMRkfpxd3YBInJxjBo1issuu6zJPjw3bNiAn59fvc8fOnQomZmZBAUFNcn3F5FLk4KKyCXMNE2sVivu7uf/T0GbNm0a9N6enp6ObeJFRBpLXT8irdBdd93FihUreO211zAMA8MwOHz4sKM75ttvv2XAgAF4eXmxcuVKDh48yKRJk4iMjMTf35+BAweyZMmSOu/5064NwzD4xz/+wQ033ICvry+dO3dmwYIFjud/2vXzwQcfEBwczLfffkv37t3x9/fn6quvJjMz0/Ga6upqHnnkEYKDgwkLC+PJJ5/kzjvv5Prrrz/n9a5Zs4bLL78cHx8f4uLieOSRRygpKalT+/PPP8/tt9+Ov78/MTExvPHGG3XeIy0tjUmTJuHv709gYCC33HILWVlZdc5ZsGABAwYMwNvbm/DwcCZPnlzn+dLSUu6++24CAgJo164d77777jnrFpHzU1ARaYVee+01kpKSuPfee8nMzCQzM5O4uDjH87/5zW+YNWsWu3fvpk+fPhQXFzNhwgSWLFlCcnIy48aNY+LEiaSlpZ3z+zz33HPccsstbNu2jQkTJjB16lTy8vLOen5paSkvvfQS//rXv/jhhx9IS0vjiSeecDz/l7/8hU8++YT333+f1atXU1hYyPz5889Zw/bt2xk3bhyTJ09m27ZtzJ07l1WrVjFt2rQ657344ov06dOHzZs3M3PmTB577DEWL14M2FuWrr/+evLy8lixYgWLFy/m4MGD3HrrrY7XL1y4kMmTJ3PNNdeQnJzM999/z4ABA+p8j5dffpkBAwaQnJzMgw8+yK9+9Sv27NlzzvpF5DyabB9mEXEpI0eONB999NE6x2q3rp8/f/55X9+jRw/zjTfecDyOj483X331VcdjwPx//+//OR4XFxebhmGY33zzTZ3vdeLECdM0TfP99983AfPAgQOO17z55ptmZGSk43FkZKT54osvOh5XV1eb7dq1MydNmnTWOu+44w7zvvvuq3Ns5cqVpsViMcvKyhy1X3311XXOufXWW83x48ebpmma3333nenm5lZna/qdO3eagLl+/XrTNE0zKSnJnDp16lnriI+PN3/2s585HttsNjMiIsJ8++23z/oaETk/taiIXIJ+2hJQUlLCb37zG3r06EFwcDD+/v7s2bPnvC0qffr0cfzbz8+PgIAAsrOzz3q+r68vCQkJjsfR0dGO8wsKCsjKymLQoEGO593c3Ojfv/85a9i0aRMffPAB/v7+jq9x48Zhs9lISUlxnJeUlFTndUlJSezevRuA3bt3ExcXV6fVqfZnUXvOli1buPLKK89Zy6k/D8MwiIqKOufPQ0TOT4NpRS5BP5298+tf/5pvv/2Wl156iU6dOuHj48NNN91EZWXlOd/Hw8OjzmPDMLDZbA063zTN046d6qfP/5TNZuP+++/nkUceOe25du3anfO1td/LNM3Tvu9Pj/v4+JzzvaDhPw8ROT+1qIi0Up6enlit1nqdu3LlSu666y5uuOEGevfuTVRUFIcPH764Bf5EUFAQkZGRrF+/3nHMarWSnJx8ztf169ePnTt30qlTp9O+PD09HeetXbu2zuvWrl1Lt27dAHvrSVpaGunp6Y7nd+3aRUFBAd27dwfsrSXff//9BV+niDSMWlREWqn27duzbt06Dh8+jL+/P6GhoWc9t1OnTsybN4+JEydiGAZPP/20U1oCHn74YWbNmkWnTp3o1q0bb7zxBidOnDhja0etJ598kiFDhvDQQw9x77334ufnx+7du1m8eHGdmT2rV6/mr3/9K9dffz2LFy/m888/Z+HChQBcddVV9OnTh6lTp/K3v/2N6upqHnzwQUaOHOnoJnvmmWe48sorSUhIYMqUKVRXV/PNN9/wm9/85uL+UEQucWpREWmlnnjiCdzc3OjRowdt2rQ553iTV199lZCQEIYOHcrEiRMZN24c/fr1a8Zq7Z588kluu+02fv7zn5OUlOQYb+Lt7X3W1/Tp04cVK1awf/9+RowYQWJiIk8//TTR0dF1znv88cfZtGkTiYmJPP/887z88suMGzcOsHfRzJ8/n5CQEC6//HKuuuoqOnbsyNy5cx2vHzVqFJ9//jkLFizgsssuY/To0axbt+7i/CBExMEwz9cBLCLiJDabje7du3PLLbfw/PPPN/p92rdvz/Tp05k+fXrTFScizUJdPyLiMlJTU/nuu+8YOXIkFRUVzJ49m5SUFG6//XZnlyYiTqKuHxFxGRaLhQ8++ICBAwcybNgwtm/fzpIlSxwDWkXk0qOuHxEREXFZalERERERl6WgIiIiIi5LQUVERERcloKKiIiIuCwFFREREXFZCioiIiLishRURERExGUpqIiIiIjL+v+I7EhY6HTNxwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 门控循环单元\n",
    "class GRU(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(GRU, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 更新门参数\n",
    "        self.W_xu, self.W_hu, self.b_u = gate_params(input_size, hidden_size)\n",
    "        # 重置门参数\n",
    "        self.W_xr, self.W_hr, self.b_r = gate_params(input_size, hidden_size)\n",
    "        # 候选隐状态参数\n",
    "        self.W_xh, self.W_hh, self.b_h = gate_params(input_size, hidden_size)\n",
    "        \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),)\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            U = torch.sigmoid(torch.mm(inputs[step], self.W_xu)\\\n",
    "                + torch.mm(hidden_state, self.W_hu) + self.b_u)\n",
    "            R = torch.sigmoid(torch.mm(inputs[step], self.W_xr)\\\n",
    "                + torch.mm(hidden_state, self.W_hr) + self.b_r)\n",
    "            H_tilda = torch.tanh(torch.mm(inputs[step], self.W_xh)\\\n",
    "                + torch.mm(R * hidden_state, self.W_hh) + self.b_h)\n",
    "            hidden_state = (1 - U) * hidden_state + U * H_tilda\n",
    "            hiddens.append(hidden_state)\n",
    "        return torch.stack(hiddens, dim=0), (hidden_state,)\n",
    "    \n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "\n",
    "gru = GRU(128, 128)\n",
    "train_rnn_lm(data_loader, gru, vocab_size, hidden_size=128, epochs=200, \n",
    "    learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69537480",
   "metadata": {},
   "source": [
    "下面在循环神经网络的基础上实现多层循环神经网络。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "6eb2e0ed",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.3014: 100%|█| 200/200 [06:00<00:00,  1.80s\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 多层循环神经网络\n",
    "class DeepRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size, num_layers, dropout=0.):\n",
    "        super(DeepRNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.num_layers = num_layers\n",
    "        self._flat_weight_names = []\n",
    "        self._all_weights = []\n",
    "        self.drop = nn.Dropout(p=dropout)\n",
    "        # 定义每一层循环神经网络的参数，由于参数数量不固定，\n",
    "        # 因此使用统一的命名方法更方便调用和管理\n",
    "        for layer in range(num_layers):\n",
    "            W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "            W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "            b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "            layer_params = (W_xh, W_hh, b_h)\n",
    "            params_names = [f'W_xh_l{layer}', f'W_hh_l{layer}', \\\n",
    "                f'b_h_l{layer}']\n",
    "            \n",
    "            # 将新的参数加入到成员列表中\n",
    "            for name, param in zip(params_names, layer_params):\n",
    "                setattr(self, name, param)\n",
    "            self._flat_weight_names.extend(params_names)\n",
    "            self._all_weights.append(params_names)\n",
    "            input_size = hidden_size\n",
    "        self._flat_weights = [getattr(self, wn) if hasattr(self, wn) \\\n",
    "            else None for wn in self._flat_weight_names]\n",
    "    \n",
    "    def __setattr__(self, attr, value):\n",
    "        if hasattr(self, '_flat_weight_names') and \\\n",
    "            attr in self._flat_weight_names:\n",
    "            idx = self._flat_weight_names.index(attr)\n",
    "            self._flat_weights[idx] = value\n",
    "        super().__setattr__(attr, value)\n",
    "    \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((self.num_layers, batch_size, hidden_size), \n",
    "            dtype=torch.float),)\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        layer_hidden_states, = states\n",
    "        layer_h_t = []\n",
    "        input_states = inputs\n",
    "        # 需要保存每一层的输出作为下一层的输入\n",
    "        for layer in range(self.num_layers):\n",
    "            hiddens = []\n",
    "            hidden_state = layer_hidden_states[layer]\n",
    "            for step in range(seq_len):\n",
    "                xh = torch.mm(input_states[step], \n",
    "                    getattr(self, f'W_xh_l{layer}'))\n",
    "                hh = torch.mm(hidden_state, getattr(self, f'W_hh_l{layer}'))\n",
    "                hidden_state = xh + hh + getattr(self, f'b_h_l{layer}')\n",
    "                hidden_state = self.drop(torch.tanh(hidden_state))\n",
    "                hiddens.append(hidden_state)\n",
    "            input_states = torch.stack(hiddens, dim=0)\n",
    "            layer_h_t.append(hidden_state)\n",
    "        return input_states, torch.stack(layer_h_t, dim=0)\n",
    "\n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "deep_rnn = DeepRNN(128, 128, 2)\n",
    "train_rnn_lm(data_loader, deep_rnn, vocab_size, hidden_size=128, \n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0f1be39",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "需要注意的是，双向循环神经网络在每个位置的输出同时包含了来自左边和右边的信息，也就是整个输入序列的信息。所以双向循环神经网络并不能用于语言模型，因为语言模型需要仅根据序列中每个词左边的信息来预测这个词。\n",
    "\n",
    "下面的双向循环神经网络是一个简单的示例，要求一次只能输入一个序列。如果想在一个批次中并行处理不同长度的输入序列以获得更高的运行效率，可以通过填充将不同长度的输入对齐。单向循环神经网络的填充较为简单，只需在每个序列末尾添加字符就可以。但是双向循环神经网络的填充更加复杂，正向和反向循环神经网络的读取顺序相反，难以保证两个方向的循环神经网络都填充在末尾，实现起来较为困难。\n",
    "解决方案参考PyTorch中的pack_padded_sequence和pad_packed_sequence。双向循环神经网络不能用于训练语言模型，因此不再提供训练示例代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0344d588",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 双向循环神经网络\n",
    "class BiRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(BiRNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 正向循环神经网络参数\n",
    "        self.W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "        # 反向循环神经网络参数\n",
    "        self.W_xh_reverse = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh_reverse = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h_reverse = nn.Parameter(torch.zeros(hidden_size))\n",
    "        \n",
    "    # 分别为正向和反向循环神经网络准备初始状态\n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),\n",
    "               torch.zeros((batch_size, hidden_size), dtype=torch.float))\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, reverse_hidden_state = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            xh = torch.mm(inputs[step], self.W_xh)\n",
    "            hh = torch.mm(hidden_state, self.W_hh)\n",
    "            hidden_state = xh + hh + self.b_h\n",
    "            hidden_state = torch.tanh(hidden_state)\n",
    "            hiddens.append(hidden_state)\n",
    "        reverse_hiddens = []\n",
    "        for step in range(seq_len-1, -1, -1):\n",
    "            xh = torch.mm(inputs[step], self.W_xh_reverse)\n",
    "            hh = torch.mm(reverse_hidden_state, self.W_hh_reverse)\n",
    "            reverse_hidden_state = xh + hh + self.b_h_reverse\n",
    "            reverse_hidden_state = torch.tanh(reverse_hidden_state)\n",
    "            reverse_hiddens.insert(0, reverse_hidden_state)\n",
    "        # 将正向和反向循环神经网络输出的隐状态拼接在一起\n",
    "        combined_hiddens = []\n",
    "        for h1, h2 in zip(hiddens, reverse_hiddens):\n",
    "            combined_hiddens.append(torch.cat([h1, h2], dim=-1))\n",
    "        return torch.stack(combined_hiddens, dim=0), ()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b79ef2c6",
   "metadata": {},
   "source": [
    "下面实现一个带有缩放点乘注意力的循环神经网络，并用其训练语言模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b5c32275",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=1.0926: 100%|█| 200/200 [07:37<00:00,  2.29s\n"
     ]
    },
    {
     "data": {
      "image/png": "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kq+//rrHr5OIuoYVFaJBatiwYdi9ezdycnIQEhKCiIiIdq/NyMjAJ598guXLl0MQBDz22GM+qQTcddddWL16NTIyMjB69Gj8/e9/R1VVVZvVDsXDDz+MWbNm4Y477sAtt9yC4OBgHDt2DJs3b/ZY2bNz5048++yzuOyyy7B582Z89NFH2LBhAwBg8eLFmDhxIlauXIkXXngBDocDv/nNbzB//nx1muzxxx/HokWLkJ6ejuuuuw4OhwNffvklHnroob79SyEa4lhRIRqkHnzwQWi1WowdOxbR0dEd9pv87W9/Q3h4OObMmYPly5dj6dKlmDp1aj+OVvLwww/j+uuvx89//nPMnj1b7TcxGo3tPmbixInYvn07Tp06hfPOOw9TpkzBY489hvj4eI/rHnjgAezbtw9TpkzBU089hb/+9a9YunQpAGmKZt26dQgPD8e8efOwePFiDB8+HB9++KH6+AULFuCjjz7C+vXrMXnyZJx//vnYvXt33/xFEJFKEDubACYi8hGXy4UxY8bgmmuuwVNPPdXt5xk2bBjuvfde3Hvvvb03OCLqF5z6ISK/kZubi6+++grz58+HzWbDSy+9hOzsbNxwww2+HhoR+QinfojIb2g0Grz11luYMWMGzj33XGRmZmLLli1qQysRDT2c+iEiIiK/xYoKERER+S0GFSIiIvJbDCpERETktxhUiIiIyG8xqBAREZHfYlAhIiIiv8WgQkRERH6LQYWIiIj81v8HV3Oqn8SVxocAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "class AttentionRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(AttentionRNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 循环神经网络参数\n",
    "        self.W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "    \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size),\\\n",
    "            dtype=torch.float),)\n",
    "    \n",
    "    # 缩放点乘注意力\n",
    "    def attention(self, query, keys, values):\n",
    "        \"\"\"\n",
    "        query: batch_size * hidden_size\n",
    "        keys/values: batch_size * prev_len * hidden_size\n",
    "        \"\"\"\n",
    "        # batch_size * 1 * hidden_size\n",
    "        query = torch.unsqueeze(query, 1)\n",
    "        # batch_size * hidden_size * prev_len\n",
    "        keys = torch.permute(keys, (0, 2, 1))\n",
    "        # batch_size * 1 * prev_len\n",
    "        attention_scores = torch.bmm(query, keys) / np.sqrt(\\\n",
    "            self.hidden_size)\n",
    "        # batch_size * 1 * prev_len\n",
    "        attention_weights = F.softmax(attention_scores, dim=1)\n",
    "        # batch_size * hidden_size\n",
    "        attention_state = torch.squeeze(torch.bmm(attention_weights,\\\n",
    "            values))\n",
    "        return attention_state\n",
    "\n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, = states\n",
    "        hiddens = []\n",
    "        attention_hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            xh = torch.mm(inputs[step], self.W_xh)\n",
    "            hh = torch.mm(hidden_state, self.W_hh)\n",
    "            hidden_state = xh + hh + self.b_h\n",
    "            hidden_state = torch.tanh(hidden_state)\n",
    "            \n",
    "            if step > 0:\n",
    "                # batch_size * hidden_size\n",
    "                query = hidden_state\n",
    "                # batch_size * prev_len * hidden_size\n",
    "                keys = values = torch.permute(torch.stack(hiddens,\\\n",
    "                    dim=0), (1, 0, 2))\n",
    "                \n",
    "                attention_state = self.attention(query, keys, values)                \n",
    "                attention_hiddens.append(attention_state)\n",
    "            else:\n",
    "                # 第0步，历史隐状态为空，无法进行注意力运算，\n",
    "                # 直接用隐状态填充\n",
    "                attention_hiddens.append(hidden_state)\n",
    "                \n",
    "            hiddens.append(hidden_state)\n",
    "        return torch.stack(attention_hiddens, dim=0), \\\n",
    "            (attention_state,)\n",
    "    \n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "\n",
    "attention_rnn = AttentionRNN(128, 128)\n",
    "train_rnn_lm(data_loader, attention_rnn, vocab_size, hidden_size=128, \n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c95d2f4b",
   "metadata": {},
   "source": [
    "下面是多头注意力的代码实现。我们在实现AttentionRNN时将注意力计算封装在成员函数里面，因此实现多头注意力时可以直接继承AttentionRNN类，只用改写构造函数和attention()成员方法即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "6373e7ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=1.3480: 100%|█| 200/200 [22:27<00:00,  6.74s\n"
     ]
    },
    {
     "data": {
      "image/png": "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09PTxb179wb823Q6naIoiuLx48fFRx99VNy1a5dYVFQkrl+/XszPzxfnzJkTEq9PFPt+jQP9exmu76HCZrOJkZGR4vPPP9/t8eHwHvb3GSGKofFvkYFKD5577jkxKytLNBgM4ty5cwO284YTAD1+vfzyy6IoimJ7e7t4wQUXiImJiaJerxczMzPFVatWiaWlpcFd+CBcf/31YmpqqqjX68W0tDTx6quvFg8cOKDe7/V6xUceeURMSUkRjUajuHjxYrGwsDCIKx6ajz/+WAQgHjlyJOD2cH0PP//88x7/bq5atUoUxYG9bx0dHeJdd90lxsXFiREREeKll14aMq+7r9dXVFTU67/Nzz//XBRFUSwtLRUXL14sxsXFiQaDQczJyRHXrFkjNjQ0BPeF+enrNQ7072W4voeKF154QYyIiBCbm5u7PT4c3sP+PiNEMTT+LQryYomIiIhCDntUiIiIKGQxUCEiIqKQxUCFiIiIQhYDFSIiIgpZDFSIiIgoZDFQISIiopDFQIWIiIhCFgMVIiIiClkMVIhoQCZOnIgnn3xywNdv3rwZgiCgubl5xNYUSgb7+yGigdEFewFENDKWLl2K0047bdg+PHft2gWz2Tzg6xctWoSqqipYrdZh+flEND4xUCEax0RRhMfjgU7X//8VJCYmDuq5DQaDekw8EdFQsfRDNAbdcsst2LJlC5566ikIggBBEFBcXKyWYz7++GPMnz8fRqMRW7duxYkTJ3DFFVcgOTkZUVFROP3007Fp06aA5+xa2hAEAX/7299w1VVXITIyEpMnT8YHH3yg3t+19PPKK68gJiYGH3/8MaZOnYqoqChcdNFFqKqqUh/jdruxZs0axMTEID4+Hg888ABWrVqFK6+8ss/Xu23bNixevBgRERHIyMjAmjVr0NbWFrD2xx57DDfddBOioqKQlpaGZ555JuA5SktLccUVVyAqKgoWiwXXXXcdampqAq754IMPMH/+fJhMJiQkJODqq68OuL+9vR3f//73ER0djczMTLz44ot9rpuI+sdAhWgMeuqpp7Bw4ULcdtttqKqqQlVVFTIyMtT777//fqxduxaHDh3CrFmz0NraiosvvhibNm1CQUEBLrzwQlx22WUoLS3t8+c8+uijuO6667Bv3z5cfPHFWLlyJRobG3u9vr29HX/4wx/wj3/8A1988QVKS0tx3333qff/9re/xRtvvIGXX34ZX331Fex2O9atW9fnGgoLC3HhhRfi6quvxr59+/D222/jyy+/xF133RVw3e9//3vMmjULe/bswUMPPYSf/OQn2LhxIwAps3TllVeisbERW7ZswcaNG3HixAlcf/316uPXr1+Pq6++GpdccgkKCgrw6aefYv78+QE/449//CPmz5+PgoIC/OhHP8Kdd96Jw4cP97l+IurHsJ3DTEQhZcmSJeLdd98dcJtydP26dev6ffy0adPEZ555Rv0+KytL/NOf/qR+D0D8n//5H/X71tZWURAEccOGDQE/q6mpSRRFUXz55ZdFAOLx48fVxzz33HNicnKy+n1ycrL4+9//Xv3e7XaLmZmZ4hVXXNHrOm+++Wbx9ttvD7ht69atokajETs6OtS1X3TRRQHXXH/99eKKFStEURTFTz75RNRqtQFH0x84cEAEIO7cuVMURVFcuHChuHLlyl7XkZWVJX73u99Vv/d6vWJSUpL4/PPP9/oYIuofMypE41DXTEBbWxvuv/9+TJs2DTExMYiKisLhw4f7zajMmjVL/bPZbEZ0dDRqa2t7vT4yMhI5OTnq96mpqer1NpsNNTU1OOOMM9T7tVot5s2b1+cadu/ejVdeeQVRUVHq14UXXgiv14uioiL1uoULFwY8buHChTh06BAA4NChQ8jIyAjIOim/C+WavXv34rzzzutzLf6/D0EQkJKS0ufvg4j6x2ZaonGo6+6dn/3sZ/j444/xhz/8Abm5uYiIiMA111yDzs7OPp9Hr9cHfC8IArxe76CuF0Wx223+ut7fldfrxQ9/+EOsWbOm232ZmZl9Plb5WaIodvu5XW+PiIjo87mAwf8+iKh/zKgQjVEGgwEej2dA127duhW33HILrrrqKsycORMpKSkoLi4e2QV2YbVakZycjJ07d6q3eTweFBQU9Pm4uXPn4sCBA8jNze32ZTAY1Ou2b98e8Ljt27cjPz8fgJQ9KS0tRVlZmXr/wYMHYbPZMHXqVABStuTTTz895ddJRIPDjArRGDVx4kTs2LEDxcXFiIqKQlxcXK/X5ubm4t1338Vll10GQRDw8MMPByUT8OMf/xhr165Fbm4u8vPz8cwzz6CpqanHbIfigQcewIIFC7B69WrcdtttMJvNOHToEDZu3Biws+err77C7373O1x55ZXYuHEj/v3vf2P9+vUAgOXLl2PWrFlYuXIlnnzySbjdbvzoRz/CkiVL1DLZI488gvPOOw85OTm44YYb4Ha7sWHDBtx///0j+0shGueYUSEao+677z5otVpMmzYNiYmJffab/OlPf0JsbCwWLVqEyy67DBdeeCHmzp07iquVPPDAA7jxxhvxve99DwsXLlT7TUwmU6+PmTVrFrZs2YJjx47hnHPOwZw5c/Dwww8jNTU14Lqf/vSn2L17N+bMmYPHHnsMf/zjH3HhhRcCkEo069atQ2xsLBYvXozly5dj0qRJePvtt9XHL126FP/+97/xwQcf4LTTTsOyZcuwY8eOkflFEJFKEPsrABMRBYnX68XUqVNx3XXX4bHHHhvy80ycOBH33HMP7rnnnuFbHBGNCpZ+iChklJSU4JNPPsGSJUvgdDrx7LPPoqioCDfddFOwl0ZEQcLSDxGFDI1Gg1deeQWnn346zjrrLBQWFmLTpk1qQysRjT8s/RAREVHIYkaFiIiIQhYDFSIiIgpZDFSIiIgoZDFQISIiopDFQIWIiIhCFgMVIiIiClkMVIiIiChkMVAhIiKikPX/AeS1pOd8xo0wAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 多头注意力循环神经网络\n",
    "class MultiHeadAttentionRNN(AttentionRNN):\n",
    "    def __init__(self, input_size, hidden_size, num_heads=4):\n",
    "        super().__init__(input_size, hidden_size)\n",
    "        # 简单起见，一般要求hidden_size能够被num_heads整除\n",
    "        assert hidden_size % num_heads == 0\n",
    "        self.num_heads = num_heads\n",
    "        # 多头注意力参数，用于将查询、键、值映射到子空间\n",
    "        self.W_aq = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_aq = nn.Parameter(torch.zeros(hidden_size))\n",
    "        self.W_ak = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_ak = nn.Parameter(torch.zeros(hidden_size))\n",
    "        self.W_av = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_av = nn.Parameter(torch.zeros(hidden_size))\n",
    "        self.W_ac = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_ac = nn.Parameter(torch.zeros(hidden_size))\n",
    "\n",
    "    # 多头缩放点乘注意力\n",
    "    def attention(self, query, keys, values):\n",
    "        \"\"\"\n",
    "        query: batch_size * hidden_size\n",
    "        keys/values: batch_size * prev_len * hidden_size\n",
    "        \"\"\"\n",
    "        query = torch.mm(query, self.W_aq) + self.b_aq\n",
    "        ori_shape = keys.size()\n",
    "        \n",
    "        keys = torch.reshape(torch.mm(torch.flatten(keys, \n",
    "                start_dim=0, end_dim=1), self.W_ak) + \n",
    "                self.b_ak, ori_shape)\n",
    "        values = torch.reshape(torch.mm(torch.flatten(values, \n",
    "                start_dim=0, end_dim=1), self.W_av) + \n",
    "                self.b_av, ori_shape)\n",
    "        # batch_size * 1 * hidden_size\n",
    "        query = torch.unsqueeze(query, 1)\n",
    "        # batch_size * hidden_size * prev_len\n",
    "        keys = torch.permute(keys, (0, 2, 1))\n",
    "        \n",
    "        head_size = self.hidden_size // self.num_heads\n",
    "        query = torch.split(query, head_size, 2)\n",
    "        keys = torch.split(keys, head_size, 1)\n",
    "        values = torch.split(values, head_size, 2)\n",
    "        \n",
    "        heads = []\n",
    "        for i in range(self.num_heads):\n",
    "            # batch_size * 1 * prev_len\n",
    "            head_scores = torch.bmm(query[i], keys[i]) / np.sqrt(\n",
    "                self.hidden_size // self.num_heads) \n",
    "            # batch_size * 1 * prev_len\n",
    "            head_weights = F.softmax(head_scores, dim=1)\n",
    "            # batch_size * head_size\n",
    "            head_state = torch.squeeze(torch.bmm(head_weights, \n",
    "                values[i])) \n",
    "            heads.append(head_state)\n",
    "        heads = torch.cat(heads, dim=1)        \n",
    "        attention_state = torch.mm(heads, self.W_ac) + self.b_ac\n",
    "\n",
    "        return attention_state\n",
    "\n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, \n",
    "    dtype=torch.long), batch_size=16, shuffle=True)\n",
    "\n",
    "mha_rnn = MultiHeadAttentionRNN(128, 128)\n",
    "train_rnn_lm(data_loader, mha_rnn, vocab_size, hidden_size=128, \n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "166d4dce",
   "metadata": {},
   "source": [
    "下面来实现Transformer模型，包括加入了位置编码的嵌入层、缩放点乘注意力、多头注意力、层归一化等具体实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "0e4110a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "代码修改自GitHub项目huggingface/transformers\n",
    "（Copyright (c) 2020, The HuggingFace Team, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 实现Transformer模型\n",
    "class EmbeddingLayer(nn.Module):\n",
    "    def __init__(self, vocab_size, max_len, embed_size):\n",
    "        super().__init__()\n",
    "        self.vocab_size = vocab_size\n",
    "        self.max_len = max_len\n",
    "        self.embed_size = embed_size\n",
    "        self.word_embedding = nn.Embedding(vocab_size, embed_size)\n",
    "        self.pos_embedding = nn.Embedding(max_len, embed_size)\n",
    "        \n",
    "    def forward(self, input_ids, pos_ids):\n",
    "        \"\"\"\n",
    "        input_ids/pos_ids: batch_size * seq_len\n",
    "        return: batch_size * seq_len * embed_size\n",
    "        \"\"\"\n",
    "        word_embed = self.word_embedding(input_ids)\n",
    "        pos_embed = self.pos_embedding(pos_ids)\n",
    "        # 将词嵌入和位置嵌入相加得到嵌入层输出\n",
    "        return word_embed + pos_embed\n",
    "\n",
    "# 缩放点乘注意力\n",
    "class ScaledDotProductAttention(nn.Module):\n",
    "    def __init__(self, dropout):\n",
    "        super().__init__()\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "    \n",
    "    def forward(self, queries, keys, values, attention_mask):\n",
    "        \"\"\"\n",
    "        queries/keys/values: batch_size * seq_len * hidden_size\n",
    "        attention_mask: batch_size * seq_len * seq_len\n",
    "        return: batch_size * seq_len * hidden_size\n",
    "        \"\"\"\n",
    "        d = queries.size(-1)\n",
    "        # 根据点乘注意力的矩阵形式计算注意力分数，除以查询向量或键向量\n",
    "        # 维度的平方根，即为缩放点乘注意力\n",
    "        scores = torch.bmm(queries, torch.transpose(keys, 1, 2)) / np.sqrt(d)\n",
    "        # 将掩码为0的位置的注意力分数设为一个大负数，根据softmax函数\n",
    "        # 的性质，这些注意力分数归一化后接近0\n",
    "        scores[attention_mask == 0] = -1e6\n",
    "        self.attention_weights = F.softmax(scores, dim=-1)\n",
    "        return torch.bmm(self.dropout(self.attention_weights), values)\n",
    "    \n",
    "class MultiHeadSelfAttention(nn.Module):\n",
    "    def __init__(self, hidden_size, num_heads, dropout):\n",
    "        super().__init__()\n",
    "        assert hidden_size % num_heads == 0\n",
    "        self.hidden_size = hidden_size\n",
    "        self.num_heads = num_heads\n",
    "        self.W_q = nn.Linear(hidden_size, hidden_size)\n",
    "        self.W_k = nn.Linear(hidden_size, hidden_size)\n",
    "        self.W_v = nn.Linear(hidden_size, hidden_size)\n",
    "        self.W_o = nn.Linear(hidden_size, hidden_size)\n",
    "        self.attention = ScaledDotProductAttention(dropout)\n",
    "    \n",
    "    def transpose_qkv(self, states):\n",
    "        # 将长度为hidden_size的向量分成num_heads个长度相等的向量\n",
    "        states = states.reshape(states.shape[0], states.shape[1],\\\n",
    "            self.num_heads, self.hidden_size // self.num_heads)\n",
    "        states = torch.permute(states, (0, 2, 1, 3))\n",
    "        return states.reshape(-1, states.shape[2], states.shape[3])\n",
    "    \n",
    "    # 与transpose_qkv的变换相反\n",
    "    def transpose_output(self, states):\n",
    "        states = states.reshape(-1, self.num_heads, states.shape[1],\\\n",
    "            states.shape[2])\n",
    "        states = torch.permute(states, (0, 2, 1, 3))\n",
    "        return states.reshape(states.shape[0], states.shape[1], -1)\n",
    "    \n",
    "    def forward(self, queries, keys, values, attention_mask):\n",
    "        \"\"\"\n",
    "        querys/keys/values: batch * seq_len * hidden_size\n",
    "        attention_mask: batch * seq_len * seq_len\n",
    "        return:\n",
    "        \"\"\"\n",
    "        # (batch_size * num_heads) * seq_len * (hidden_size / num_heads)\n",
    "        queries = self.transpose_qkv(self.W_q(queries))\n",
    "        keys = self.transpose_qkv(self.W_k(keys))\n",
    "        values = self.transpose_qkv(self.W_v(values))\n",
    "        # 重复张量的元素，用以支持多个注意力头的运算\n",
    "        # (batch_size * num_heads) * seq_len * seq_len\n",
    "        attention_mask = torch.repeat_interleave(attention_mask,\\\n",
    "            repeats=self.num_heads, dim=0)\n",
    "        # (batch_size * num_heads) * seq_len * (hidden_size / num_heads)\n",
    "        output = self.attention(queries, keys, values, attention_mask)\n",
    "        # batch * seq_len * hidden_size\n",
    "        output_concat = self.transpose_output(output)\n",
    "        return self.W_o(output_concat)\n",
    "\n",
    "# 两层前馈神经网络\n",
    "class PositionWiseFNN(nn.Module):\n",
    "    def __init__(self, hidden_size, intermediate_size):\n",
    "        super().__init__()\n",
    "        self.dense1 = nn.Linear(hidden_size, intermediate_size)\n",
    "        self.relu = nn.ReLU()\n",
    "        self.dense2 = nn.Linear(intermediate_size, hidden_size)\n",
    "        \n",
    "    def forward(self, X):\n",
    "        return self.dense2(self.relu(self.dense1(X)))\n",
    "\n",
    "# 层归一化\n",
    "class LayerNorm(nn.Module):\n",
    "    def __init__(self, normalized_shape, eps=1e-6):\n",
    "        super().__init__()\n",
    "        self.gamma = nn.Parameter(torch.ones(normalized_shape))\n",
    "        self.beta = nn.Parameter(torch.zeros(normalized_shape))\n",
    "        # 一个小量用于数值稳定（防止除0）\n",
    "        self.eps = eps\n",
    "        \n",
    "    def forward(self, hidden_states):\n",
    "        mean = torch.mean(hidden_states, -1, keepdim=True)\n",
    "        std = torch.std(hidden_states, -1, keepdim=True)\n",
    "        return self.gamma * (hidden_states - mean) / (std +\\\n",
    "            self.eps) + self.beta\n",
    "\n",
    "# 将两个输入相加并归一化\n",
    "class AddNorm(nn.Module):\n",
    "    def __init__(self, hidden_size, dropout):\n",
    "        super().__init__()\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "        self.layer_norm = LayerNorm(hidden_size)\n",
    "        \n",
    "    def forward(self, X, Y):\n",
    "        return self.layer_norm(self.dropout(Y) + X)\n",
    "    \n",
    "# 一个完整的Transformer层\n",
    "class TransformerLayer(nn.Module):\n",
    "    def __init__(self, hidden_size, num_heads, dropout, intermediate_size):\n",
    "        super().__init__()\n",
    "        self.self_attention = MultiHeadSelfAttention(hidden_size,\\\n",
    "            num_heads, dropout)\n",
    "        self.add_norm1 = AddNorm(hidden_size, dropout)\n",
    "        self.fnn = PositionWiseFNN(hidden_size, intermediate_size)\n",
    "        self.add_norm2 = AddNorm(hidden_size, dropout)\n",
    "    \n",
    "    def forward(self, X, attention_mask):\n",
    "        Y = self.add_norm1(X, self.self_attention(X, X, X, attention_mask))\n",
    "        return self.add_norm2(Y, self.fnn(Y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2fd3f8f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 在Transformer模型基础上加上语言模型需要的输入输出、损失计算等\n",
    "class TransformerLM(nn.Module):\n",
    "    def __init__(self, vocab_size, max_len, hidden_size, num_layers,\\\n",
    "                 num_heads, dropout, intermediate_size):\n",
    "        super().__init__()\n",
    "        self.embedding_layer = EmbeddingLayer(vocab_size, max_len,\\\n",
    "            hidden_size)\n",
    "        self.num_layers = num_layers\n",
    "        # 使用ModuleList保存多个Transformer层，注意不能使用Python列表，\n",
    "        # Python列表保存的PyTorch变量无法自动求导\n",
    "        self.layers = nn.ModuleList([TransformerLayer(hidden_size,\\\n",
    "            num_heads, dropout, intermediate_size)\\\n",
    "            for _ in range(num_layers)])\n",
    "        self.output_layer = nn.Linear(hidden_size, vocab_size)\n",
    "        \n",
    "    def forward(self, input_ids):\n",
    "        # 这里实现的forward()函数一次只能处理一句话，\n",
    "        # 如果想要支持批次运算，实现起来会更复杂，也会引入冗余操作\n",
    "        seq_len = input_ids.size(0)\n",
    "        assert input_ids.ndim == 1 and seq_len <= \\\n",
    "            self.embedding_layer.max_len\n",
    "        \n",
    "        # 1 * seq_len\n",
    "        input_ids = torch.unsqueeze(input_ids, dim=0)\n",
    "        pos_ids = torch.unsqueeze(torch.arange(seq_len), dim=0)\n",
    "        # 定义下三角掩码，用于语言模型训练\n",
    "        # 1 * seq_len * seq_len\n",
    "        attention_mask = torch.unsqueeze(torch.tril(torch.ones((seq_len,\\\n",
    "            seq_len), dtype=torch.int32)), dim=0)\n",
    "        # 1 * seq_len * hidden_size\n",
    "        hidden_states = self.embedding_layer(input_ids, pos_ids)\n",
    "        for layer in self.layers:\n",
    "            hidden_states = layer(hidden_states, attention_mask)\n",
    "        outputs = self.output_layer(hidden_states)\n",
    "        \n",
    "        loss_fct = nn.CrossEntropyLoss(ignore_index=0)\n",
    "        loss = loss_fct(outputs[:, :-1].squeeze(),\\\n",
    "            input_ids[:, 1:].squeeze())\n",
    "        return loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e459fc19",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-49, loss=0.5878: 100%|█| 50/50 [09:06<00:00, 10.93s/it\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 训练TransformerLM，由于不再采取批次训练，因此不再使用RNNLM和data_loader\n",
    "def train_transformer_lm(data, model, epochs=50, learning_rate=1e-3):\n",
    "    optimizer = Adam(model.parameters(), lr=learning_rate)\n",
    "    model.zero_grad()\n",
    "    model.train()\n",
    "    \n",
    "    epoch_loss = []\n",
    "    with trange(epochs, desc='epoch', ncols=60) as pbar:\n",
    "        for epoch in pbar:\n",
    "            step_loss = []\n",
    "            np.random.shuffle(data)\n",
    "            for step, x in enumerate(data):\n",
    "                loss = model(torch.tensor(x, dtype=torch.long))\n",
    "                pbar.set_description(f'epoch-{epoch},'+\\\n",
    "                    f' loss={loss.item():.4f}')\n",
    "                loss.backward()\n",
    "                grad_clipping(model)\n",
    "                optimizer.step()\n",
    "                model.zero_grad()\n",
    "                step_loss.append(loss.item())\n",
    "            # 本章前面的模型训练使用batch_size为16，\n",
    "            # TransformerLM出于简便实现只能使用batch_size为1\n",
    "            # 因此TransformerLM每一步的损失方差会更大，\n",
    "            # 为便于对比，取每个epoch最后16个样本的平均损失\n",
    "            epoch_loss.append(np.mean(step_loss[-16:]))\n",
    "    \n",
    "    epoch_loss = np.array(epoch_loss)\n",
    "    plt.plot(range(len(epoch_loss)), epoch_loss)\n",
    "    plt.xlabel('training epoch')\n",
    "    plt.ylabel('loss')\n",
    "    plt.show()\n",
    "    \n",
    "sent_tokens = dataset.convert_tokens_to_ids()\n",
    "max_len=40\n",
    "for i, tokens in enumerate(sent_tokens):\n",
    "    tokens = tokens[:max_len]\n",
    "    tokens += [0] * (max_len - len(tokens))\n",
    "    sent_tokens[i] = tokens\n",
    "sent_tokens = np.array(sent_tokens)\n",
    "\n",
    "model = TransformerLM(vocab_size, max_len=40, hidden_size=128,\\\n",
    "    num_layers=1, num_heads=4, dropout=0., intermediate_size=512)\n",
    "train_transformer_lm(sent_tokens, model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7b0dd09-c708-4f9a-bfd9-976da7cbcddb",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
